﻿using System;
using System.Web.Services.Discovery;
using System.Xml.Linq;


namespace MockingBird.Wsdl.Parser
{
    using System.IO;

    public class RemoteSinglePartWsdlRetriever : IWsdlRetriever
    {
        private Uri wsdlUri;
        private DiscoveryClientProtocol client;
        private string localWsdlPath;

        public RemoteSinglePartWsdlRetriever(Uri targetUri)
        {
            if (targetUri == null)
                throw new ArgumentNullException("targetUri", "targetUri is null.");

            this.client = new DiscoveryClientProtocol();
            this.wsdlUri = targetUri;
            //get the service name which is at the end of the url without the .wsdl extension
            this.ServiceName = Path.GetFileNameWithoutExtension(targetUri.Segments[targetUri.Segments.Length - 1]);
        }

        public IWsdlRetrieverSettings Settings { get; set; }

        public string ServiceName
        {
            get;
            private set;
        }


        public XDocument GetWsdl()
        {
            if (this.Settings == null)
            {
                Settings = new WsdlRetrieverSettings();
            }
            if (Settings.HasNonInitializedValues)
            {
                Settings.SetDefaults(this.ServiceName);
            }

            //if it is a local file then dont bother downloading the metadata
            // simply point to the file path
            if (wsdlUri.IsFile)
            {
                this.localWsdlPath = wsdlUri.LocalPath;
            }
            else
            {
                DownloadMetadata();
            }


            //Simply load up the wsdl document and return it
            XDocument wsdlDoc = XDocument.Load(localWsdlPath);
            return wsdlDoc;
        }

        private void DownloadMetadata()
        {
            //Setup the folder where we download the metadata
            //Now we append the service name to the folder to get a full path where we can store the files

            string workingFolder = Settings.DownloadLocationRoot;

            //if it isnt already available, lets create it
            if (!Directory.Exists(workingFolder))
            {
                Directory.CreateDirectory(workingFolder);
            }

            //Now discover the wsdl and resolve all references
            client.Credentials = Settings.Credentials;
            client.DiscoverAny(wsdlUri.AbsoluteUri);
            client.ResolveAll();

            //dowload the wsdl and associated files to the specified folder
            client.WriteAll(workingFolder, "discovery.xml");
            localWsdlPath = Directory.GetFiles(workingFolder, "*.wsdl")[0];
        }

    }
}
